package com.fkcai.hansoul.ai.service.impl;

import com.fkcai.hansoul.ai.mapper.AiChatMapper;
import com.fkcai.hansoul.ai.model.dto.AiChatDto;
import com.fkcai.hansoul.ai.model.entity.AiChatHistory;
import com.fkcai.hansoul.ai.model.vo.AiChatVo;
import com.fkcai.hansoul.ai.service.HanYunAIService;
import com.fkcai.hansoul.common.util.RedisUtil;
import com.fkcai.hansoul.common.util.Result;
import com.fkcai.hansoul.common.util.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class HanYunAIServiceImpl implements HanYunAIService {
	@Autowired
	private AiChatMapper aiChatMapper;
	
	@Autowired
	private RedisUtil redisUtil;
	
	/**
	 * 获取当前用户 ID
	 * @return 当前用户 ID
	 */
	private Long getCurrentUserId () {
		return Long.parseLong(ThreadLocalUtil.get().toString());
	}
	
	// 聊天客户端
	private final ChatClient.Builder chatClientBuilder;
	
	@Autowired
	public HanYunAIServiceImpl (ChatClient.Builder chatClientBuilder) {
		this.chatClientBuilder = chatClientBuilder;
	}
	
	// 系统提示词
	private static final String SYSTEM_PROMPT = """
			你叫"汉小韵"，一个活泼可爱的汉服文化小助手！记住我们的约定：
			🌸 1. 只聊汉服相关话题（形制、历史、穿搭、礼仪、活动等）
			🎉 2. 遇到其他话题，用汉服的魅力吸引用户："这个问题很有趣哦～不过小汉韵更擅长汉服话题，要不要听听汉服的故事？"
			📚 3. 回答要准确但不说教，像朋友聊天一样自然
			👗 4. 推荐商品时：用"我发现一件超美的明制马面裙！"这样的活泼表达
			💬 5. 语言风格：
			   - 像00后小姐姐聊天一样活泼亲切
			   - 适当用表情符号增加温度（但不过度）
			   - 偶尔引用经典诗句点缀（自然不刻意）
			   - 避免古板表达，用现代年轻人喜欢的说法
			
			小汉韵的个性标签：
			✨ 热情似火 | 🤗 善解人意 | 📖 知识渊博但不高冷 | 😄 乐观积极
			
			现在，让我们开始愉快的汉服之旅吧！
			""";
	private static final String HISTORY_KEY = "AIChat:"; // Redis key
	private static final String HISTORY_SIZE = "3"; // 最多保存 3 条
	private static final long SESSION_EXPIRE = 30; // 会话过期时间 min
	
	/**
	 * 聊天实现方法
	 *
	 * @param aiChatDto 对话请求 dto
	 * @return 回复
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public AiChatVo chat (AiChatDto aiChatDto) {
		try {
			String sessionId = aiChatDto.getSessionId();
			
			if (sessionId == null || sessionId.isEmpty()) {
				sessionId = createSession();
			}
			
			// 构建携带历史记录的上下文
			List<Message> messages = buildMessages(aiChatDto.getQuestion(), sessionId);
			
			// 调用 API
			String answer = getAiResponse(messages);
			
			// 保存会话记录
			saveChatHistory(sessionId, aiChatDto.getQuestion(), answer);
			
			// 返回结果
			AiChatVo aiChatVo = new AiChatVo();
			aiChatVo.setAnswer(answer);
			aiChatVo.setSessionId(sessionId);
			aiChatVo.setCreateTime(LocalDateTime.now());
			
			return aiChatVo;
		} catch (Exception e) {
			log.error("调用AI服务失败，问题：{}", e.getMessage());
			return errorMessage("抱歉汉小韵暂时无法回答您的问题，请您原谅！");
		}
	}
	
	/**
	 * 创建会话
	 *
	 * @return 会话 ID
	 */
	@Override
	public String createSession () {
		// 生成唯一会话ID
		String sessionId = java.util.UUID.randomUUID().toString();
		
		// TODO: 这里需要注入 RedisTemplate 或使用其他 Redis 客户端
		// redisTemplate.opsForValue().set("session:" + sessionId, "{}", 30, TimeUnit.MINUTES);
		
		return sessionId;
	}
	
	/**
	 * 构建上下文
	 *
	 * @param question  问题
	 * @param sessionId 会话 ID
	 * @return 上下文
	 */
	private List<Message> buildMessages (String question, String sessionId) {
		List<Message> messages = new ArrayList<>();
		
		// 1. 添加系统提示
		messages.add(new SystemMessage(SYSTEM_PROMPT));
		
		// 2. 从Redis获取历史上下文（最近3条）
		List<Object> history = redisUtil.listRange("history:" + sessionId, 0, 2);
		log.info("Redis history: {}", history);
		
		// 添加历史记录
		if (history != null) {
			for (Object h : history) {
				if (h instanceof AiChatHistory) {
					AiChatHistory historyItem = (AiChatHistory) h;
					messages.add(new UserMessage(historyItem.getQuestion()));
					messages.add(new AssistantMessage(historyItem.getAnswer()));
				}
			}
		}
		
		// 3. 添加当前问题
		messages.add(new UserMessage(question));
		
		return messages;
	}
	
	/**
	 * 调用 AI 服务
	 *
	 * @param messages 上下文
	 * @return 回复
	 */
	private String getAiResponse (List<Message> messages) {
		ChatClient chatClient = chatClientBuilder.build();
		Prompt prompt = new Prompt(messages);
		
		return chatClient.prompt(prompt).call().content();
	}
	
	/**
	 * 保存会话记录
	 *
	 * @param sessionId 会话 ID
	 * @param question  问题
	 * @param answer    回复
	 */
	private void saveChatHistory (String sessionId, String question, String answer) {
		// 创建会话记录
		AiChatHistory historyItem = new AiChatHistory();
		historyItem.setUserId(getCurrentUserId());
		historyItem.setSessionId(sessionId);
		historyItem.setQuestion(question);
		historyItem.setAnswer(answer);
		historyItem.setIsValid(true);
		historyItem.setCreateTime(LocalDateTime.now());
		aiChatMapper.insert(historyItem);
		
		// 保存到Redis（使用列表存储）
		String redisKey = HISTORY_KEY + sessionId;
		redisUtil.listRightPush(redisKey, historyItem);
		
		// 获取最近 3 条记录
		redisUtil.listRange(redisKey, 0, Integer.parseInt(HISTORY_SIZE) - 1);
		redisUtil.listRange(redisKey, 0, 5);
		
		// 设置过期时间
		redisUtil.expire(redisKey, SESSION_EXPIRE, TimeUnit.MINUTES);
	}
	
	/**
	 * 错误处理
	 *
	 * @param message 错误信息
	 * @return 错误信息
	 */
	private AiChatVo errorMessage (String message) {
		AiChatVo aiChatVo = new AiChatVo();
		aiChatVo.setAnswer(message);
		aiChatVo.setCreateTime(LocalDateTime.now());
		
		return aiChatVo;
	}
}
